﻿using Fast;
using Fast.Extensions.DatabaseAccessor.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection.Extensions;
using System;
using System.Collections.Concurrent;

namespace Microsoft.Extensions.DependencyInjection
{
    /// <summary>
    /// 数据库访问器服务扩展类
    /// </summary>
    [SkipScan]
    public static class DatabaseAccessServiceCollectionExtensions
    {
        /// <summary>
        /// 添加数据库上下文
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <param name="configure">配置</param>
        /// <param name="migrationAssemblyName">迁移类库名称</param>
        /// <returns>服务集合</returns>
        public static IServiceCollection AddDatabaseAccessor(this IServiceCollection services, Action<DatabaseAccessorOptions> configure, string migrationAssemblyName = default)
        {
            //配置数据库连接选项
            services.AddConfigureOptions<DatabaseConnectionOptions>();

            //创建数据库访问器选项对象
            var options = new DatabaseAccessorOptions(services, migrationAssemblyName);

            //执行数据库访问器配置
            configure?.Invoke(options);

            // 注册 Sql 非泛型仓储
            services.TryAddScoped<ISqlRepository, SqlRepository>();

            //注册泛型仓储
            services.TryAddScoped<IRepository, Repository>();
            services.TryAddScoped(typeof(IRepository<>), typeof(Repository<>));
            services.TryAddScoped(typeof(IRepository<,>), typeof(Repository<,>));

            //注入用数据库上下文定位器定位具体上下文实例的委托
            services.TryAddScoped(sp =>
            {
                Func<Type, DbContext> buildContextFunc = locator =>
                {
                    var dbContextType = DatabaseHelper.GetDbContextByLocator(locator);

                    var dbContext = sp.GetService(dbContextType) as DbContext;

                    var dbContextManager = sp.GetService<IDbContextManager>();
                    dbContextManager.AddContext(dbContext);

                    return dbContext;
                };

                return buildContextFunc;
            });

            services.TryAddScoped<IDbContextManager, DbContextManager>();
            services.TryAddScoped<IUnitOfWork, UnitOfWork>();
            //添加过滤器
            services.AddMvcFilter<UnitOfWorkFilter>();

            return services;
        }
    }
}
